package com.zlzlib.okhttp.utils;

import com.zlzlib.okhttp.xml.SoapEnvelope;
import okhttp3.*;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
 * http三方请求工具
 *
 * @DateTime: 2023/8/22 11:27
 * @Author zlz
 * @Version 1.0
 */
@Component
public class HttpRequestUtil {

    private final OkHttpClient okHttpClient;

    public HttpRequestUtil(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    /**
     * 执行请求
     *
     * @param request 请求体
     * @return 结果
     */
    private String doCall(Request request) {
        try (Response response = okHttpClient.newCall(request).execute()) {
            // 处理响应结果
            if (response.isSuccessful() && response.body() != null) {
                Charset charset = null;
                MediaType mediaType = response.body().contentType();
                if (mediaType != null && mediaType.charset() != null) {
                    charset = mediaType.charset();
                }
                if (charset == null) {
                    charset = StandardCharsets.UTF_8;
                }
                //判断是否需要解码
                String encoding = response.header("Content-Encoding");
                if (encoding != null && encoding.toLowerCase().contains("gzip")) {
                    return new String(gZip(response.body().source().readByteArray()), charset);
                }
                return response.body().source().readString(charset);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
        return "";
    }

    private byte[] gZip(byte[] bytes) {
        GZIPInputStream gzipInputStream = null;
        ByteArrayOutputStream outputStream = null;
        try {
            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
            gzipInputStream = new GZIPInputStream(inputStream);
            outputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = gzipInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            return outputStream.toByteArray();
        } catch (Exception ignored) {
        } finally {
            if (gzipInputStream != null) {
                try {
                    gzipInputStream.close();
                } catch (IOException ignored) {
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException ignored) {
                }
            }
        }
        return bytes;
    }

    /**
     * Get请求
     *
     * @param url 请求地址
     * @return 结果
     */
    public String getRequest(String url) {
        return getRequest(url, null);
    }

    /**
     * Get请求
     *
     * @param url   请求地址
     * @param param 参数
     * @return 返回结果
     */
    public String getRequest(String url, Map<String, Object> param) {
        return getRequest(url, param, new Headers.Builder());
    }

    /**
     * Get请求
     *
     * @param url   地址
     * @param param 参数
     * @param head  请求头数据
     * @return 返回结果
     */
    public String getRequest(String url, Map<String, Object> param, Headers.Builder head) {
        if (param != null) {
            // 构建URL，并添加查询参数
            HttpUrl httpUrl = HttpUrl.parse(url);
            if (httpUrl != null) {
                HttpUrl.Builder urlBuilder = httpUrl.newBuilder();
                for (String key : param.keySet()) {
                    urlBuilder.addQueryParameter(key, param.get(key).toString());
                }
                url = urlBuilder.build().toString();
            }
        }
        Request request = new Request.Builder().url(url)
                .headers(head.build()).build();
        return doCall(request);
    }

    /**
     * post请求参数为json串
     *
     * @param url  地址
     * @param json 参数
     * @return 结果
     */
    public String postRequestJson(String url, String json) {
        return postRequest(url, RequestBody.create(json, OkHttpUtil.mediaJson()), new Headers.Builder());
    }

    /**
     * post请求
     *
     * @param url         地址
     * @param requestBody 请求体
     * @return 结果
     */
    public String postRequest(String url, RequestBody requestBody) {
        return postRequest(url, requestBody, new Headers.Builder());
    }

    /**
     * post请求
     *
     * @param url         地址
     * @param requestBody 请求体
     * @param head        头部数据
     * @return 结果
     */
    public String postRequest(String url, RequestBody requestBody, Headers.Builder head) {
        Request request = new Request.Builder().url(url)
                .post(requestBody)
                .headers(head.build()).build();
        return doCall(request);
    }

    /**
     * soap请求
     *
     * @param url          地址
     * @param soapAction   请求的soap接口方法
     * @param soapEnvelope soap请求体
     * @return 结果
     */
    public String postSoap(String url, String soapAction, SoapEnvelope soapEnvelope) {
        Headers.Builder head = new Headers.Builder();
        head.add("SOAPAction", soapAction)
                .add("Content-Type", "text/xml;charset=UTF-8")
                .add("Connection", "Keep-Alive")
                .add("Accept-Encoding", "gzip,deflate");
        try {
            head.add("Host", new URL(url).getHost());
        } catch (MalformedURLException ignored) {
        }
        return postRequest(url, soapEnvelope.getRequestBody(), head);
    }

}